/*
 * Created by SharpDevelop.
 * User: David
 * Date: 2006-12-20
 * Time: 02:42
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;

using patterns;

using Labb4.Pooman.Cards;
using Labb4.Pooman.Players;

namespace Labb4.Pooman.Game
{
	/// <summary>
	/// The table, holding the graphical areas where cards are positioned
	/// 
	/// Implements the Singleton design pattern
	/// Implements the Observer design pattern
	/// </summary>
	public sealed class Table : Observer<GameState>
	{
		#region members
		
		/// <summary>
		/// The one instance
		/// </summary>
		private static Table				m_Instance = new Table();
		
		/// <summary>
		/// Should never be logically used, TODO: remove
		/// </summary>
		private List<CardPile>				m_CardsOnTable;
		/// <summary>
		/// Should never be logically used, TODO: remove
		/// </summary>
		private List<CardPile>				m_TurnedCards;
		
		/// <summary>
		/// Reference to the state of the game
		/// </summary>
		private TableGameState				m_GamePhase;
		/// <summary>
		/// The table's state in phase 1 of the game
		/// </summary>
		private TableGameStatePhase1		m_GamePhase1;
		/// <summary>
		/// The table's state in phase 2 of the game
		/// </summary>
		private TableGameStatePhase2		m_GamePhase2;
		
		/// <summary>
		/// The left graphical area of the table
		/// </summary>
		private CardArea					m_LeftArea;
		/// <summary>
		/// The right graphical area of the table
		/// </summary>
		private CardArea					m_RightArea;
		/// <summary>
		/// The bottom graphical area of the table
		/// </summary>
		private CardArea					m_BottomArea;
		
		#endregion
		
		#region constructors
		
		/// <summary>
		/// Constructor, initializes members
		/// </summary>
		private Table()
		{
			m_CardsOnTable = new List<CardPile>();
			m_TurnedCards = new List<CardPile>();
			
			m_GamePhase = null;
			m_GamePhase1 = new TableGameStatePhase1();
			m_GamePhase2 = new TableGameStatePhase2();
			
			m_LeftArea = new CardArea(20, 60, 80, 380, true, "left");
			m_RightArea = new CardArea(700, 60, 80, 380, true, "right");
			m_BottomArea = new CardArea(120, 440, 560, 120, false, "bottom");
		}
		
		#endregion
		
		#region methods
		
		/// <summary>
		/// Adds cards to the table's m_CardsOnTable
		/// </summary>
		/// <param name="cards"></param>
		public void PlayCards(CardPile cards)
		{
			m_CardsOnTable.Add(cards);
		}
		
		/// <summary>
		/// Gets cards from the table in accordance to the phase the game is in
		/// </summary>
		/// <param name="player"></param>
		public void GetCards(Player player)
		{
			m_GamePhase.GetCards(player);
		}
		
		/// <summary>
		/// Turns cards on the table, deprecated TODO: remove
		/// </summary>
		public void TurnCards()
		{
			foreach(CardPile itPile in m_CardsOnTable)
			{
				foreach(Card itCard in itPile)
				{
					itCard.ResetCard();
				}
				
				m_TurnedCards.Add(itPile);
			}
			
			m_CardsOnTable.Clear();
		}
		
		/// <summary>
		/// Removes the oldest played cards. Deprecated, TODO: remove
		/// </summary>
		public void RemoveBottomCardPile()
		{
			if(m_CardsOnTable.Count > 0)
			{
				m_CardsOnTable.RemoveAt(0);
			}
		}
		
		/// <summary>
		/// Clears all the cards from the table, deprecated, TODO: remove
		/// </summary>
		public void ClearTable()
		{
			foreach(CardPile it in m_CardsOnTable)
			{
				it.Remove(it);
			}
			
			foreach(CardPile it in m_TurnedCards)
			{
				it.Remove(it);
			}
			
			m_CardsOnTable.Clear();
			m_TurnedCards.Clear();
		}
		
		#endregion
		
		#region overrides
		
		/// <summary>
		/// Switches the state of the table in accordance with the state of the game
		/// Is this really needed? Does the table have to be an observer?
		/// TODO: determine this
		/// </summary>
		protected override void UpdateObserver()
		{
			base.UpdateObserver();
			
			if(m_SubjectsState is GameStatePhase1)
			{
				m_GamePhase = m_GamePhase1;
			}
			else
			{
				m_GamePhase = m_GamePhase2;
			}
		}
		
		#endregion
		
		#region properties
		
		/// <summary>
		/// The one instance (get)
		/// </summary>
		public static Table Instance
		{
			get
			{
				return m_Instance;
			}
		}
		
		/// <summary>
		/// The cards on the table (get)
		/// </summary>
		public List<CardPile> CardsOnTable
		{
			get
			{
				return m_CardsOnTable;
			}
		}
		
		/// <summary>
		/// The table's graphical left area (get)
		/// </summary>
		public CardArea LeftArea
		{
			get
			{
				return m_LeftArea;
			}
		}
		
		/// <summary>
		/// The table's graphical right area (get)
		/// </summary>
		public CardArea RightArea
		{
			get
			{
				return m_RightArea;
			}
		}
		
		/// <summary>
		/// The table's graphical bottom area (get)
		/// </summary>
		public CardArea BottomArea
		{
			get
			{
				return m_BottomArea;
			}
		}
		
		#endregion
	}
}
